package com.example.demo.yanglq.component.jedis;

import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author by yanglq
 * @Classname RedisClient
 * @Description TODO
 * @Date 2019/12/18/018 16:39
 */
//@Component
public class RedisClient {
    private RedisTemplate redisTemplate;

    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public RedisTemplate<String, Object> getRedisTemplate() {
        return redisTemplate;
    }

    public void set(String key, String val) throws Exception {
        ValueOperations ops = redisTemplate.opsForValue();
        ops.set(key, val);
    }

    public Boolean set(String key, String val, long expireSecond) throws Exception {
        ValueOperations ops = redisTemplate.opsForValue();
        ops.set(key, val);
        return redisTemplate.expire(key, expireSecond, TimeUnit.SECONDS);
    }

    public String get(String key) throws Exception {
        ValueOperations ops = redisTemplate.opsForValue();
        return (String) ops.get(key);
    }

    public Boolean exists(String key) throws Exception {
        return redisTemplate.hasKey(key);
    }

    public Map<String, String> hgetAll(String name) {
        return redisTemplate.opsForHash().entries(name);
    }

    public void expire(String name, Integer expiredTime) {
        redisTemplate.expire(name, expiredTime, TimeUnit.SECONDS);
    }

    public void hmset(String name, Map<String, String> map) {
        redisTemplate.opsForHash().putAll(name, map);
    }

    public Boolean bitget(String key, Long offset) {
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        return ops.getBit(key, offset);
    }

    public void bitset(String key, Long offset, Boolean b) {
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        ops.setBit(key, offset, b);
    }

    /**
     * 统计bit位为1的总数
     *
     * @param key
     */
    public Long bitCount(String key) {
        return (Long) redisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
    }

    public Long bitCount(String key, int start, int end) {
        return (Long) redisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes(), start, end));
    }

    public Long incr(String key) {
        return redisTemplate.getConnectionFactory().getConnection().incr(
                redisTemplate.getKeySerializer().serialize(key)
        );
    }

    public void del(String... keys) {
        for (String key : keys
                ) {
            redisTemplate.delete(key);
        }
    }

    public List<Boolean> bitgets(String key, long[] offsets) {
        List results = redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
            for (long offset : offsets) {
                bitget(key, offset);
            }
            return null;
        });
        List<Boolean> list = new ArrayList<>();
        results.forEach(obj -> {
            list.add((Boolean) obj);
        });
        return list;
    }
}
